#include <stdio.h>
#include "pwm_led.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "driver/ledc.h"

#include "esp_log.h"
#include "esp_err.h"

#define LEDC_FREQUENCY          (5000)                  //PWM周期

//定义LED的GPIO口
#define LED_GPIO  GPIO_NUM_27

static const char *TAG = "PWM";

static void pwm_task(void *arg);


void pwm_config(void)
{
    ESP_LOGI(TAG, "PWM Configuration");
    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_TIMER_13_BIT,//周期10位
        .freq_hz = 5000,                    //频率5kHz
        .speed_mode = LEDC_LOW_SPEED_MODE,  //低速模式
        .timer_num = LEDC_TIMER_0,          //定时器0
        .clk_cfg = LEDC_AUTO_CLK            //自动选择时钟
    };

    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    //ledc通道初始化
    ledc_channel_config_t ledc_channel = {
        .speed_mode     = LEDC_LOW_SPEED_MODE,        //低速模式
        .channel        = LEDC_CHANNEL_0,     //PWM 通道0-7
        .timer_sel      = LEDC_TIMER_0,       //关联定时器，也就是上面初始化好的那个定时器
        .intr_type      = LEDC_INTR_DISABLE,//不使能中断
        .gpio_num       = LED_GPIO,   //设置输出PWM方波的GPIO管脚
        .duty           = 0, // 设置默认占空比为0
        .hpoint         = 0//设置占空比的起始点
    };

    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
    xTaskCreatePinnedToCore(pwm_task, "pwm_task", 1024, NULL, 10, NULL, 1);  // 创建 PWM 任务      
}


static void pwm_task(void *arg)
{
    unsigned int duty = 0;
    uint8_t pwm_state = 0;
    while (1)
    {
        ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 8191*duty/500)); // 设置占空比
        ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); // 更新占空比
        if(pwm_state)
        {
            duty--;
            if(duty==0)pwm_state = 0;
        }
        else
        {
            duty++;
            if(duty==500)pwm_state = 1;
        }
       
        vTaskDelay(10 / portTICK_PERIOD_MS); // 延时 10ms
      
    }
}